""" DigitalICS: mobile data collection tool to complete surveys with integrated multimedia

    Copyright (C) 2009. Yael Schwartzman  

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>
    
    Contact information: Yael Schwartzman -  yaelsf@gmail.com
    """

import appuifw,os,e32
import audio as player
import key_codes,graphics,thread
from api.logger import logger
from api.lang import Lang,Properties

"""  class that allows audio to be played as part of any appuifw  widget. Can act as DigitalICS' API"""
p= Properties()
l = Lang(p.LANGUAGE)

show_lock = thread.allocate_lock()

if e32.in_emulator():
    audio_path = "c:\\System\\Apps\\digitalics\\audio"
    image_path = "c:\\System\\Apps\\digitalics\\img"
else:
    audio_path = "e:\digitalics\\audio"    
    image_path = "e:\\digitalics\\img"


def _play_sound(audio,file_path = None):
    """ play the sound and return the object or return none""" 
    if e32.in_emulator():
        return None
    if audio is None:
        return None
    if file_path is None:
        file_path = audio_path
    if not audio.endswith(".wav"):
        if not audio.endswith(".amr"):
            audio = "%s.amr" % audio 
    filename=u"%s\\%s"%(file_path,audio)
    sound_obj= None
    if audio and os.path.exists(filename):
        sound_obj = player.Sound.open(filename)
        sound_obj.play()

    return sound_obj
     
def note( message, type , audio = None): 

    sound_obj = _play_sound(audio)
    
    appuifw.note(message, type)
    
    if audio and sound_obj:
        sound_obj.close()
      

def query(message,type,audio = None, def_value = None): 
    sound_obj = _play_sound(audio)

    ans = appuifw.query(message,type,def_value)

    if audio and sound_obj:
        sound_obj.close()
    
    return ans

def boolean(title,audio=None, def_value = None):
    index =  selection_list(choices = [u'%s'%l.YES,u'%s'%l.NO],title = title, audio= audio, def_value = def_value )
    if index == 0: return l.YES
    elif index == 1: return l.NO
    else: return None
    
def selection_list(choices, search_field = 0, audio = None, title = None,def_value = None):
    sound_obj = None
    if title: 
        appuifw.app.title = u'%s' % title 
    
    change = True
    index = def_value
    if def_value: 
        choices = _get_choice_list_with_default(choices,def_value)
        index = appuifw.selection_list(choices = choices, search_field= search_field)
    else:
            sound_obj = _play_sound(audio) 
            index = appuifw.selection_list(choices = choices, search_field= search_field)
    
    if audio and sound_obj:
        sound_obj.close()
    
    return index

def multi_selection_list(choices,style,search_field= 0,title = None, audio= None,
                         def_value = None):
    sound_obj = None
    if title: 
        appuifw.app.title = u'%s' % title 
    
    change = True
    index = def_value
    
    if def_value: 
        sound_obj = _play_sound(audio)
        #print "choices before %s" % choices 
        #for now just put an X behind it so that people now that's the selection
        choices = _get_multi_choice_list_with_default(choices,def_value)
        #print "choices after %s" % choices
        index = appuifw.multi_selection_list(choices = choices, style = style,search_field= search_field)
        #print "after index"    
    else:
        sound_obj = _play_sound(audio)
        index = appuifw.multi_selection_list(choices = choices, style = style,search_field= search_field)
            
    if audio and sound_obj:
        sound_obj.close()
    
    return index

def _get_choice_list_with_default(choices,def_value):
    new_choices = []
    for i in choices:
        if i == def_value:
            new_choices.append(u"X-%s"%i)
        else:
            new_choices.append(u"%s"% i)
    return new_choices

def _get_multi_choice_list_with_default(choices,def_value):
    new_choices = []
    #print " def_value %s " % def_value 
    if  type(def_value) =='tuple':
        def_list = list(def_value)
        for i in def_list:
            choices[i] = "X-%s" % choices[i]
        return choices
    for i in choices:
        #print "type %s" % type(def_value)
        if type(def_value)== 'list':
            #print "list"
            if i in def_value:
                new_choices.append(u"X-%s"%i)
            else:
                new_choices.append(u"%s"% i)
        elif type(def_value) == type('str'):
            #print "str"
            if i == def_value:
                new_choices.append(u"X-%s"%i)
            else:
                new_choices.append(u"%s"% i)
            
    #print "before return %s " % new_choices
    return new_choices

def record(filename,media_path ,title = None,audio =None,inspector = None):
    global recorded,recording_obj
    
    recorded = False
    recording_obj = None
    
    if title is None:
        title = l.RECORD_AUDIO
    title = u"%s"% title 

    if audio is None: 
        audio = l.A_RECORD_AUDIO
    
        
    def stop_recording(cancel = False):
        global recording_obj,recorded
        if recording_obj is not None:
            recording_obj.stop()
            recording_obj.close()
            note(unicode(l.AUDIO_RECORDED),"conf")
            recorded = True
        else:
            note(unicode(l.AUDIO_NOT_RECORDED),"conf")
            logger.log_error("recording_obj is None %s "% title)
        if cancel:
            return False
        else:
            return True

    def quit_recording():
        return stop_recording(cancel = True)
    
    filename = os.path.join(media_path,filename)
        
    if query(title,"query",audio= audio):
        text_body = appuifw.Text(unicode(l.RECORDING))
        text_body.font = u'LatinBold80',
        text_body.bind(key_codes.EKeyYes,stop_recording)
    
        appuifw.app.title = title
        appuifw.app.exit_key_handler=quit_recording
        appuifw.app.menu = [(unicode(l.STOP), stop_recording)]
        appuifw.app.body = text_body 
        
        recording_obj = player.Sound.open(u'%s'%filename)
        recording_obj.record()
        while recording_obj.state()== player.ERecording and not recorded: # recording
            e32.ao_sleep(0.1)
            e32.ao_yield() 
        return recorded
    else:
        return False

def take_picture(filename,media_path,title = None, audio = None,inspector = None):
    global finder_on,image
    finder_on = True  
    image = None
    
    if title: 
        appuifw.app.title = u'%s' % title
    else:
        appuifw.app.title = unicode(l.TAKE_PICTURE)
        
    if not audio:
        audio = l.A_TAKE_PICTURE

    def quit_picture():
        return picture_callback(cancel = True)
        
    def picture_callback(cancel = False):
        global finder_on
        image = None
        camera.stop_finder()
        
        if cancel:
            note(unicode(l.PICTURE_CANCELLED),"conf")
            finder_on = False
        else:
            image = camera.take_photo(flash = 'auto')
            picfile = os.path.join(media_path,filename)
            image.save(picfile)
            
            note(unicode(l.PICTURE_SAVED),"conf",l.A_PICTURE_SAVED)
            appuifw.app.orientation= 'portrait'
            appuifw.app.screen="normal"
            finder_on = False
        
    def viewfinder_callback(img):
        if image:
            appuifw.app.body.blit(image)
        else:
            if type(appuifw.app.body)== 'appuifw.Listbox': 
                finder_on = False
            else:
                if type(img) =='tuple':
                    print "Not image %s type %s" %(str(img),type(img))
                else:
                    appuifw.app.body.blit(img)
                
    if query(appuifw.app.title,"query",audio= audio):    
        appuifw.app.menu = [(unicode(l.TAKE_PICTURE), picture_callback)]
        canvas=appuifw.Canvas(event_callback=None, redraw_callback=viewfinder_callback)
        canvas.bind(key_codes.EKeyYes,picture_callback)
        appuifw.app.exit_key_handler=quit_picture
        appuifw.app.screen="full"
        appuifw.app.body=canvas
        appuifw.app.orientation= 'landscape'
        import camera
        
        camera.start_finder(viewfinder_callback, size=(500,500))
        while finder_on:
            e32.ao_yield()
            
        return True
    else:
        return False 
    

        
def show_picture(path,filename): 
    global finished_loading, img
    finished_loading =  False       
    full_name = os.path.join(path,filename)
    backup_image=graphics.Image.new((255,255))

    if os.path.exists(full_name):     
        filename = u"%s" % full_name
    else:
        filename = u"%s" % os.path.join(image_path,"not_exists.bmp")
    
    def handle_loading(evt):
        global finished_loading,finished_showing
        
        canvas.blit(img,target=(0, 0, w, h), scale = 1)
        finished_loading = True
        finished_showing = False

    imginfo=graphics.Image.inspect(filename)
    img = graphics.Image.new(imginfo['size'])
    img.load(filename,callback = handle_loading)
    
        
    def handle_redraw(evt):
        global finished_loading
        if finished_loading:
            backup_image.text(textloc,u'')
            img.resize((320,240),keepaspect=1)
            canvas.blit(img,target=(0, 0, w, h), scale = 1)
        else:
            canvas.blit(backup_image)
   
    canvas = appuifw.Canvas(event_callback = None, redraw_callback=handle_redraw)
    w,h = canvas.size

    textloc=(w*0.3,h*.5)
    backup_image.blit(img,target=(0, 0, w, h), scale = 1)
    backup_image.text(textloc,unicode(l.IMAGE_LOADING),(255,0,0),font = u'LatinBold30')

    canvas.blit(backup_image)
    canvas.clear(0)
    return canvas
        

def show_audio(path,file):
    global quit_playing,sound_obj
    quit_playing = False
    sound_obj = _play_sound(file_path = path,audio = file)
        
    w,h = (255,255)
    textloc=(0,h*.3)
    backup_image=graphics.Image.new((w,h))
    backup_image.text(textloc,u'%s'%file,(255,0,0),font = u'LatinBold30')

    def start_new_audio_thread(evt):
        thread.start_new_thread(quit_playing,())
        
    def quit_playing():
        e32.ao_sleep(.3)
        global quit_playing,sound_obj
        show_lock.acquire()
        quit_playing = True
        if sound_obj:
            sound_obj.close()
        show_lock.release()
        
        
    def handle_redraw(evt):
        global sound_obj
        w,h = canvas.size        
        if sound_obj.state()== player.EPlaying:
            canvas.blit(backup_image,target=(0, 0, 255,255), scale = 1)
        else:
            backup_image.text(textloc,l.END_OF_RECORDING,(255,0,0),font = u'LatinBold30')
        
    canvas = appuifw.Canvas(event_callback = None, redraw_callback=handle_redraw)
    canvas.bind(key_codes.EKeyLeftArrow,start_new_audio_thread)
    canvas.bind(key_codes.EKeyRightArrow,start_new_audio_thread)
    return canvas        
                

